import { NameSpace } from 'utils/index';
import { getPathWithNoRootPath } from 'utils/router';
import exceed from 'utils/apimap';
// import reducerRegistry from 'pages/index/reducers/reducerRegistry';
// import { getReducers } from '../containers/interface';
import { updateSetSelectedType } from 'pages/index/pages/project/pages/projectFiles/actions/common';
import intl from '../../../locale';

const ns = NameSpace('index');
export const UPDATE_PAGE_INFO = ns('UPDATE_PAGE_INFO');
export const RELOAD_START = ns('RELOAD_START');
export const RELOAD_END = ns('RELOAD_END');
export const UPDATE_PAGE_INFO_END = ns('UPDATE_PAGE_INFO_END');
export const UPDATE_PAGE_INFO_FROM_PROJECT = ns('UPDATE_PAGE_INFO_FROM_PROJECT');
export const RECEIVE_NEWBIE_TASK_EXPAND_STATUS = ns('RECEIVE_NEWBIE_TASK_EXPAND_STATUS');
export const RECEIVE_NEWBIE_TASK_STATUS = ns('RECEIVE_NEWBIE_TASK_STATUS');
export const UPDATE_PROJECT_TAB_COUNT = ns('UPDATE_PROJECT_TAB_COUNT');

export function updateNewbieTaskExpandStatus(status) {
  return (dispatch) => {
    dispatch({
      type: RECEIVE_NEWBIE_TASK_EXPAND_STATUS,
      data: status,
    });
  };
}

export function updateNewbieTaskStatus(status) {
  return (dispatch) => {
    dispatch({
      type: RECEIVE_NEWBIE_TASK_STATUS,
      data: status,
    });
  };
}

function assignOrClearObj(parentObj, key) {
  const newObj = parentObj[key];
  if (newObj && Object.keys(newObj).length) {
    window.FORCE[key] = Object.assign(window.FORCE[key], newObj);
  } else {
    const props = Object.keys(window.FORCE[key]);
    for (let i = 0; i < props.length; i++) {
      delete window.FORCE[key][props[i]];
    }
  }
}

function getProjectTabPromise(pageInfo) {
  if (pageInfo && pageInfo.pathResource && pageInfo.pathResource.type === 'PROJECT') {
    let revision = 'master';
    const { resourceSubject } = pageInfo;
    if (resourceSubject) {
      if (resourceSubject.revisionType === 'commits') {
        revision = resourceSubject.revision;
      }
      if (resourceSubject.revisionType === 'branch') {
        revision = `refs/heads/${resourceSubject.revision}`;
      }
      if (resourceSubject.revisionType === 'tag') {
        revision = `refs/tags/${resourceSubject.revision}`;
      }
    }
    return new Promise((resolve, reject) => {
      exceed
        .fetch({
          api: 'project.overview',
          params: {
            repoId: window.FORCE.pathResource.id,
          },

          data: {
            revision,
          },
        })
        .then((res) => {
          resolve(res);
        })
        .fail((err) => {
          reject(err);
        });
    });
  }
}

export function getProjectTabInfo() {
  return (dispatch, getState) => {
    const state = getState().root;
    const { pageInfo } = state;
    // 库不存在时不调用
    if (pageInfo && pageInfo.pathResource && pageInfo.pathResource.isExist === 'false') {
      return;
    }
    const projectTabReq = getProjectTabPromise(pageInfo);
    if (projectTabReq) {
      projectTabReq.then((projectTabInfo) => {
        const result = JSON.parse(JSON.stringify(pageInfo));
        if (result.pathResource && projectTabInfo) {
          result.pathResource.branchCount = `${projectTabInfo.branch_count || 0}`;
          result.pathResource.commitCount = `${projectTabInfo.commit_count || 0}`;
          result.pathResource.mergeRequestCount = `${projectTabInfo.mr_count || 0}`;
          result.pathResource.repoSize = `${projectTabInfo.repo_size || 0}`;
          result.pathResource.tagCount = `${projectTabInfo.tag_count || 0}`;
          result.pathResource.renewal_flag = projectTabInfo.renewal_flag;
          result.pathResource.plan_type = projectTabInfo.plan_type;
          result.pathResource.history_scale_repo = projectTabInfo.history_scale_repo;
        }
        assignOrClearObj(result, 'pathResource');
        dispatch({
          type: UPDATE_PROJECT_TAB_COUNT,
          data: result,
        });
      });
    }
  };
}

// 调用 /spa 接口获取页面渲染必要的信息
// assetsName未变化时，不会重新加载页面，除非locationState未指定forceUpdate:true
export function fetchPageInfo(path, locationState, cb) {
  return (dispatch, getState) => {
    const state = getState().root;
    const { pageInfo } = state;
    const { search } = window.location;
    let extraPath = '';
    if (search.includes('source_type=Namespace')) {
      extraPath = '?source_type=Namespace';
    }
    exceed
      .fetch({
        api: 'spa.path',
        data: {
          path: getPathWithNoRootPath(path + extraPath) || '/',
        },
      })
      .then((res) => {
        if (res.success) {
          const { result } = res;

          // 若assetsName未变化且locationState未指定forceUpdate:true，则无需加载新页面
          if (
            pageInfo.assetsName === result.assetsName &&
            !(locationState && locationState.forceUpdate)
          ) {
            // 处理 projectFiles 的特殊情况
            if (pageInfo.assetsName === 'projectFiles') {
              dispatch(updateSetSelectedType(result));
            }

            return;
          }

          // 避免先清空后恢复的闪动问题，保留旧数据
          if (
            result.pathResource &&
            result.pathResource.id &&
            result.pathResource.type === 'PROJECT' &&
            pageInfo.pathResource
          ) {
            result.pathResource.branchCount = `${pageInfo.pathResource.branchCount || 0}`;
            result.pathResource.commitCount = `${pageInfo.pathResource.commitCount || 0}`;
            result.pathResource.mergeRequestCount = `${
              pageInfo.pathResource.mergeRequestCount || 0
            }`;
            result.pathResource.repoSize = `${pageInfo.pathResource.repoSize || 0}`;
            result.pathResource.tagCount = `${pageInfo.pathResource.tagCount || 0}`;
            result.pathResource.renewal_flag = pageInfo.pathResource.renewal_flag;
            result.pathResource.plan_type = pageInfo.pathResource.plan_type;
            result.pathResource.history_scale_repo = pageInfo.pathResource.history_scale_repo;
          }

          // FIXME 待商榷
          assignOrClearObj(result, 'pathResource');
          assignOrClearObj(result, 'resourceSubject');
          assignOrClearObj(result, 'codeReviewDetail');
          window.FORCE.assetsName = result.assetsName;
          window.FORCE.title = result.title;

          dispatch({
            type: UPDATE_PAGE_INFO,
            data: result,
          });

          dispatch(resetChildPageState(result.assetsName));

          dispatch({
            type: UPDATE_PAGE_INFO_END,
          });

          dispatch(getProjectTabInfo());

          // bootYundou(window.FORCE);
          // 若assetsName相同，且指定了forceUpdate需则重载
          if (
            pageInfo.assetsName === result.assetsName &&
            locationState &&
            locationState.forceUpdate
          ) {
            dispatch({
              type: RELOAD_START,
            });
          }
        } else {
          const { errorAction, errorCode, errorMessage, errorTraceId } = res;

          if (res.result && res.result.pathResource) {
            assignOrClearObj(res.result, 'pathResource');
          }

          dispatch({
            type: UPDATE_PAGE_INFO,
            data: {
              assetsName: 'error',
              title: intl.get({
                id: 'code-assets.index.actions.AnErrorOccurredYunxiaoCodeup',
                defaultMessage: '出错啦 · 云效 Codeup',
              }),
              errorCode,
              errorMessage,
              errorAction,
              errorTraceId,
            },
          });
        }

        cb && cb();
      })
      .fail((err) => {
        const errRes = JSON.parse(err.responseText);
        const { errorAction, errorCode, errorMessage, errorTraceId } = errRes;
        dispatch({
          type: UPDATE_PAGE_INFO,
          data: {
            assetsName: 'error',
            title: intl.get({
              id: 'code-assets.index.actions.AnErrorOccurredYunxiaoCodeup',
              defaultMessage: '出错啦 · 云效 Codeup',
            }),
            errorCode,
            errorMessage,
            errorAction,
            errorTraceId,
          },
        });

        cb && cb();
      });
  };
}

// 单纯更新pageInfo
export function updatePageInfo(path, cb) {
  return (dispatch) => {
    const { search } = window.location;
    let extraPath = '';
    if (search.includes('source_type=Namespace')) {
      extraPath = '?source_type=Namespace';
    }
    exceed
      .fetch({
        api: 'spa.path',
        data: {
          path: getPathWithNoRootPath(path + extraPath) || '/',
        },
      })
      .then((res) => {
        if (res.success) {
          const { result } = res;

          // FIXME 待商榷
          assignOrClearObj(result, 'pathResource');
          assignOrClearObj(result, 'resourceSubject');
          assignOrClearObj(result, 'codeReviewDetail');
          window.FORCE.assetsName = result.assetsName;
          window.FORCE.title = result.title;

          dispatch({
            type: UPDATE_PAGE_INFO_FROM_PROJECT,
            data: result,
          });
        } else {
          const { errorAction, errorCode, errorMessage, errorTraceId } = res;
          dispatch({
            type: UPDATE_PAGE_INFO,
            data: {
              assetsName: 'error',
              title: intl.get({
                id: 'code-assets.index.actions.AnErrorOccurredYunxiaoCodeup',
                defaultMessage: '出错啦 · 云效 Codeup',
              }),
              errorCode,
              errorMessage,
              errorAction,
              errorTraceId,
            },
          });
        }

        cb && cb();
      })
      .fail((err) => {
        const errRes = JSON.parse(err.responseText);
        const { errorAction, errorCode, errorMessage, errorTraceId } = errRes;
        dispatch({
          type: UPDATE_PAGE_INFO,
          data: {
            assetsName: 'error',
            title: intl.get({
              id: 'code-assets.index.actions.AnErrorOccurredYunxiaoCodeup',
              defaultMessage: '出错啦 · 云效 Codeup',
            }),
            errorCode,
            errorMessage,
            errorAction,
            errorTraceId,
          },
        });

        cb && cb();
      });
  };
}

// 重载一个页面
export function reload(cb) {
  return (dispatch) => {
    dispatch(fetchPageInfo(window.location.pathname, { forceUpdate: true }, cb));
  };
}

export function reloadEnd() {
  return (dispatch) => {
    dispatch({
      type: RELOAD_END,
    });
  };
}

// 重置子页面的状态
export function resetChildPageState(assetsName) {
  return (dispatch, getState) => {
    dispatch({
      type: `${assetsName}-UPDATE_PAGE_INFO`,
      data: getState().root.pageInfo,
    });
  };
}
